package com.yunpuvip.sachet.biz.service.impl;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.yunpuvip.sachet.biz.entity.BalanceHistory;
import com.yunpuvip.sachet.biz.entity.Order;
import com.yunpuvip.sachet.biz.entity.Payment;
import com.yunpuvip.sachet.biz.mapper.PaymentMapper;
import com.yunpuvip.sachet.biz.model.params.PaymentParam;
import com.yunpuvip.sachet.biz.model.result.PaymentResult;
import com.yunpuvip.sachet.biz.service.BalanceHistoryService;
import com.yunpuvip.sachet.biz.service.OrderService;
import  com.yunpuvip.sachet.biz.service.PaymentService;
import cn.stylefeng.roses.core.util.ToolUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yunpuvip.sachet.modular.constant.enumconstant.OrderStatus;
import com.yunpuvip.sachet.modular.constant.enumconstant.PayStatus;
import com.yunpuvip.sachet.modular.core.exception.GunsException;
import com.yunpuvip.sachet.modular.page.LayuiPageFactory;
import com.yunpuvip.sachet.modular.page.LayuiPageInfo;
import com.yunpuvip.sachet.modular.util.sms.Sendsms;
import com.yunpuvip.sachet.modular.vo.rest.request.BalanceReqVo;
import com.yunpuvip.sachet.modular.vo.rest.request.PaymentReqVo;
import com.yunpuvip.sachet.modular.vo.rest.response.PaymentRspVo;
import lombok.extern.slf4j.Slf4j;
import net.bytebuddy.implementation.bytecode.Throw;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.Serializable;
import java.util.Date;
import java.util.List;

/**
 * <p>
 * 支付账单 服务实现类
 * </p>
 *
 * @author wushaohong
 * @since 2019-08-10
 */
@Service
@Slf4j
public class PaymentServiceImpl extends ServiceImpl<PaymentMapper, Payment> implements PaymentService {


    @Autowired
    private OrderService orderService;

    @Autowired
    private BalanceHistoryService balanceHistoryServicel;

    @Override
    public void add(PaymentParam param){
        Payment entity = getEntity(param);
        this.save(entity);
    }

    @Override
    public void delete(PaymentParam param){
        this.removeById(getKey(param));
    }

    @Override
    public void update(PaymentParam param){
        Payment oldEntity = getOldEntity(param);
        Payment newEntity = getEntity(param);
        ToolUtil.copyProperties(newEntity, oldEntity);
        this.updateById(newEntity);
    }

    @Override
    public PaymentResult findBySpec(PaymentParam param){
        return null;
    }

    @Override
    public List<PaymentResult> findListBySpec(PaymentParam param){
        return null;
    }

    @Override
    public LayuiPageInfo findPageBySpec(PaymentParam param){
        Page pageContext = getPageContext();
     /*   QueryWrapper<Payment> objectQueryWrapper = new QueryWrapper<>();
        IPage page = this.page(pageContext, objectQueryWrapper);
        return LayuiPageFactory.createPageInfo(page);*/
        Page<Payment> paymentPage = baseMapper.getPaymentPage(pageContext, param);
        return LayuiPageFactory.createPageInfo(paymentPage);

    }

    private Serializable getKey(PaymentParam param){
        return param.getId();
    }

    private Page getPageContext() {
        return LayuiPageFactory.defaultPage();
    }

    private Payment getOldEntity(PaymentParam param) {
        return this.getById(getKey(param));
    }

    private Payment getEntity(PaymentParam param) {
        Payment entity = new Payment();
        ToolUtil.copyProperties(param, entity);
        return entity;
    }

    @Override
    public boolean isPaymentOk(Payment payment) {
        if(ObjectUtil.isNull(payment)){
            return false;
        }
        Integer orderId = payment.getOrderId();
        Integer payStatus = payment.getPayStatus();
        Date expireDate = payment.getExpireDate();
        if(!PayStatus.WAIT_PAY.getStatus().equals(payStatus)){
            return false;
        }
        //是否过期
        if(expireDate.before(new Date())){
            return false;
        }
        if(ObjectUtil.isNotNull(orderId)){
            //判断订单是否正常
            Order order = orderService.getById(orderId);
            if(ObjectUtil.isNull(order)){
                return false;
            }
            if(!PayStatus.WAIT_PAY.getStatus().equals(order.getPayStatus())){
                return false;
            }

        }
        return true;
    }

    @Override
    public boolean NotifyTOUpadtePaymentAndAddBalanceRecord ( Payment payment ) {
        String orderNo = payment.getOrderNo();
        Payment myPayment = getPaymentByOrderNo(orderNo);
        myPayment.setPayStatus(PayStatus.PAID.getStatus());
        myPayment.setPayTime(new Date());
        myPayment.setPayMethod(payment.getPayMethod());
        baseMapper.updateById(myPayment);
        Integer orderId = myPayment.getOrderId();
        if(ObjectUtil.isNotNull(orderId)){
            //订单支付回调处理
            Order order = orderService.getById(orderId);
            if(order==null){
                log.error("订单未找到：{}",orderId);

                return  false;
            }
            order.setPayPrice(myPayment.getAmount());
            order.setPayStatus(PayStatus.PAID.getStatus());
            order.setOrderStatus(OrderStatus.PAID.getStatus());
            order.setPayTime(new Date());
            orderService.updateById(order);
        }else {
            //充值支付回调处理
            //插入充值变动的记录
            Integer integer = balanceHistoryServicel.insertAddBanlanceHistory(myPayment);

        }

        return true;

    }

    @Override
    public Payment getPaymentByOrderNo(String orderNo) {
        LambdaQueryWrapper<Payment> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Payment::getOrderNo,orderNo);
        return baseMapper.selectOne(wrapper);
    }
    @Override
    public Page<PaymentRspVo> getPaymentPage(PaymentReqVo paymentReqVo) {
        Integer day = paymentReqVo.getDay();
        if(day>0) {
            DateTime dateTime = DateUtil.offsetDay(new Date(),-1*day);
            paymentReqVo.setFindDate(DateUtil.format(dateTime,"yyyy-MM-dd HH:mm:ss"));
        }
        Page pageContext = getPageContext();
       return baseMapper.getPaymentPageByCondition(pageContext,paymentReqVo);

    }


    @Override
    public void updateExpiredOrderAndPayment() {
        LambdaQueryWrapper<Payment> paymentLambdaQueryWrapper = new LambdaQueryWrapper<>();
        paymentLambdaQueryWrapper.lt(Payment::getExpireDate,new Date());
        paymentLambdaQueryWrapper.eq(Payment::getPayStatus,PayStatus.WAIT_PAY.getStatus());
        List<Payment> paymentList = baseMapper.selectList(paymentLambdaQueryWrapper);
        paymentList.stream().forEach(p->{
            p.setPayStatus(PayStatus.CANCLE.getStatus());
            baseMapper.updateById(p);
        });
        orderService.updateExpiredOrder();
    }

    public static void main(String[] args) {
        System.out.println(DateUtil.parseDateTime("2010-10-10 10:10:10").before(new Date()));
    }

    @Override
    public boolean isFisrtPay(Integer playerId) {
        LambdaQueryWrapper<Payment> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Payment::getPayStatus,PayStatus.PAID.getStatus());
        return !(baseMapper.selectCount(wrapper)>0);
    }
}
